package org.spring.aicloud.controller.model;


import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionRequest;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.spring.aicloud.entity.Answer;
import org.spring.aicloud.entity.myenum.AiModelEnum;
import org.spring.aicloud.entity.myenum.AiTypeEnum;
import org.spring.aicloud.service.IAnswerService;
import org.spring.aicloud.util.AppVariable;
import org.spring.aicloud.util.ResponseEntity;
import org.spring.aicloud.util.SecurityUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 字节豆包大模型控制器
 */
@RestController
@RequestMapping("/doubao")
@Tag(name = "豆包大模型")
public class DoubaoController {

    @Value("${doubao.api-key}")
    private String apiKey;
    @Value("${doubao.url}")
    private String url;
    @Value("${doubao.model-id}")
    private String modelId;
    @Resource
    private IAnswerService answerService;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @RequestMapping("/chat")
    public ResponseEntity test(String question) {
        if (!StringUtils.hasLength(question)){
            return ResponseEntity.fail("请输入问题");
        }
        //在调用接口之前，先针对用户加锁
        //创建key
        String lockKey = AppVariable.getModelLockKey
                (SecurityUtil.getCurrentUser().getUid(),
                        AiModelEnum.DOUBAO.getValue(), AiTypeEnum.CHAT.getValue());
        String result = ""; //大模型返回的结果
        boolean save = false;//数据是否保存成功
        //创建分布式锁实例
        RLock lock = redissonClient.getLock(lockKey);
        //尝试获取分布式锁
        boolean isLock = false;
        try {
            isLock = lock.tryLock(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        if (!isLock) {
            //获取分布式锁失败
            return ResponseEntity.fail("请勿频繁调用接口");
        }
        try {
            //1.apikey,调用url地址
            ArkService service = ArkService.builder().apiKey(apiKey).
                    baseUrl(url).build();
            //2.构建问题对象
            List<ChatMessage> messages = new ArrayList<>();
            ChatMessage chatMessage = ChatMessage.
                    builder().
                    role(ChatMessageRole.USER).
                    content(question).
                    build();
            messages.add(chatMessage);
            //3.创建chat
            ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
                    .model(modelId) //接入点的id（并不是大模型的名字）
                    .messages(messages)
                    .build();
            //4.进行对话并得到对话的结果
            result = service.createChatCompletion(chatCompletionRequest).
                    getChoices()
                    .get(0)
                    .getMessage()
                    .getContent().toString();
            //5.将对话信息保存到数据库中
            Answer answer = Answer.builder()
                    .title(question)
                    .content(result)
                    .uid(SecurityUtil.getCurrentUser().getUid())
                    .model(AiModelEnum.DOUBAO.getValue())
                    .type(AiTypeEnum.CHAT.getValue())
                    .build();
            save = answerService.save(answer);
        }catch (Exception ignored){}
        finally {
            //3.释放锁
            lock.unlock();
        }
        if (save) {
            return ResponseEntity.success(result);
        }
        return ResponseEntity.fail("请求操作失败,请重试！");
    }
    /**
     * 查询历史对话信息
     */
    @PostMapping("/chatlist")
    public ResponseEntity getChatList() {
        //首先获取到当前的登录用户和调用的大模型
        long uid = SecurityUtil.getCurrentUser().getUid();
        int type = AiTypeEnum.CHAT.getValue();
        int model = AiModelEnum.DOUBAO.getValue();
        //将当前的uid和type和model封装成一个key
        String cacheKey = AppVariable.getListCacheKey(uid,model,type);
        //获取缓存
        Object value = redisTemplate.opsForValue().get(cacheKey);
        if (value == null){
            //缓存为空，就去查询数据库
            List<Answer> list = answerService.lambdaQuery().
                    eq(Answer::getUid, SecurityUtil.getCurrentUser().getUid()).
                    eq(Answer::getModel, AiModelEnum.DOUBAO.getValue()).
                    eq(Answer::getType, AiTypeEnum.CHAT.getValue()).
                    orderByDesc(Answer::getAid).
                    list();
            //查询到结果之后，将结果存入到缓存中
            redisTemplate.opsForValue().set(cacheKey,list,1, TimeUnit.DAYS);
            //存入缓存之后，返回结果
            return ResponseEntity.success(list);
        }else {
            //查到了缓存，直接返回
            return ResponseEntity.success(value);
        }
    }
}
